package controller;

import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import testutil.ScoreComputationBeanRemote;
import dao.CandidateHistoryDAORemote;
import dao.CategoryDAORemote;
import dao.InterviewDAORemote;
import dto.CandidateDTO;
import dto.CandidateHistoryDTO;
import dto.InterviewDTO;

@ManagedBean
@SessionScoped
public class CandidateHistoryController implements Serializable {

	private static final long serialVersionUID = 1L;

	@EJB
	CandidateHistoryDAORemote candidateHistoryDAO;
	@EJB
	ScoreComputationBeanRemote scoreComputationDAO;
	@EJB
	CategoryDAORemote categoryDAO;
	
	@EJB
	InterviewDAORemote interviewDAO;

	private CandidateDTO candidateDTO;
	private CandidateHistoryDTO candidateHistoryDTO;
	private InterviewDTO viewDetailsInterview;
	// private InterviewDTO test;
	private List<InterviewDTO> allInterviews;
	private List<InterviewDTO> pendingInterviews;
	private List<InterviewDTO> acceptedInterviews;
	private List<InterviewDTO> declinedInterviews;
	private boolean hasPendingInterviews;
	private boolean hasAcceptedInterviews;
	private boolean hasDeclinedInterviews;
	private boolean hasHistory;
	private boolean viewTest;
	private boolean showPendingInterviews;
	private HtmlDataTable dataTable;
	private HtmlDataTable dataTableAccepted;
	private HtmlDataTable dataTableHistory;
	private String interviewTest;
	private Map<String, String> scorePerCategories;
	private boolean hasScore;
	private boolean noScore;
	private float totalScore = 1;
	private String messageClass;
	private int currentInterviewId;
	
	
	//@PostConstruct
	public void createLists(){
//		System.out.println(candidateDTO.getLastName());
		candidateHistoryDAO.refreshCandidate(candidateDTO);
		setAllInterviews(candidateHistoryDAO.getAllInterviewsForCandidate(candidateDTO));
		System.out.println("allInterviews size=" + allInterviews.size());
		setPendingInterviews(pendingInterviews);
		setAcceptedInterviews(acceptedInterviews);
		System.out.println("acceptedInterviews size=" + acceptedInterviews.size());
		setDeclinedInterviews(declinedInterviews);
	}

	public void setCandidateHistoryDTO(CandidateHistoryDTO candidateHistoryDTO) {
		this.candidateHistoryDTO = candidateHistoryDTO;
	}

	public CandidateHistoryDTO getCandidateHistoryDTO() {
		return candidateHistoryDTO;
	}

	public void setAllInterviews(List<InterviewDTO> allInterviews) {
		this.allInterviews = allInterviews;
	}

	public List<InterviewDTO> getAllInterviews() {
		return allInterviews;
	}

	public void setPendingInterviews(List<InterviewDTO> pendingInterviews) {
		List<InterviewDTO> l = new ArrayList<InterviewDTO>();
		for (InterviewDTO i : allInterviews)
			if (i.getAccepted() == -1)
				l.add(i);
		this.pendingInterviews = l;
	}

	public List<InterviewDTO> getPendingInterviews() {
		return pendingInterviews;
	}

	public void acceptTest() {
		InterviewDTO aI = (InterviewDTO) getDataTable().getRowData();
		aI.setAccepted((byte) 1);
		candidateHistoryDAO.updatePendingInterview(aI);
		createLists();
		System.out.println("accept interviul cu id " + aI.getId());
		// setPendingInterviews(pendingInterviews);
		// setAcceptedInterviews(acceptedInterviews);
		// setDeclinedInterviews(declinedInterviews);
	}

	public void declineTest() {
		InterviewDTO aI = (InterviewDTO) getDataTable().getRowData();
		aI.setAccepted((byte) 0);
		candidateHistoryDAO.updatePendingInterview(aI);
		createLists();
		System.out.println("decline interviul cu id " + aI.getId());
		// setPendingInterviews(pendingInterviews);
		// setAcceptedInterviews(acceptedInterviews);
		// setDeclinedInterviews(declinedInterviews);
	}

	public void setAcceptedInterviews(List<InterviewDTO> acceptedInterviews) {
		List<InterviewDTO> l = new ArrayList<InterviewDTO>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		for (InterviewDTO i : allInterviews)
			try {
				if (i.getAccepted() == 1
						&& (i.getDate().after(new Date()) || sdf.format(i.getDate()).equals(sdf.format(new Date())))&&(scoreComputationDAO.computeCorrectAnswersPerCategories(i.getId()).size()==0 || !scoreComputationDAO.isInterviewStarted((i.getId()))))
					l.add(i);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		this.acceptedInterviews = l;
	}

	public List<InterviewDTO> getAcceptedInterviews() {
		return acceptedInterviews;
	}

	public void setDeclinedInterviews(List<InterviewDTO> declinedInterviews) {
		List<InterviewDTO> l = new ArrayList<InterviewDTO>();
		for (InterviewDTO i : allInterviews)
			if (i.getAccepted() == 0)
				l.add(i);
		this.declinedInterviews = l;
	}

	public List<InterviewDTO> getDeclinedInterviews() {
		return declinedInterviews;
	}

	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}

	public HtmlDataTable getDataTable() {
		return dataTable;
	}

	public void generateTest(ActionEvent event) {
		InterviewDTO test = (InterviewDTO) getDataTableAccepted().getRowData();

		Date currentDate = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String s = "";
		if (sdf.format(test.getDate()).equals(sdf.format(currentDate))) {
			// String
			// s=String.valueOf(sdf.format(aI.getDate()).equals(sdf.format(currentDate)));
			interviewDAO.generateQuestions(test);
			s = test.getTemplate().getTitle() + " has been generated! Press Start test! ";
			messageClass = "info";
			test.setGenerated(true);
			test.setGenerateButtonStyleClass("buttonDis");
			test.setStartTest(false);
			test.setStartButtonStyleClass("button");
			// dataTableAccepted.setValue(test);
			System.out.println("acceptedInterviews size=" + acceptedInterviews.size());
			//createLists();
		} else {
			s = "Your test can be generated only on " + test.getDateString();
			messageClass = "errorMessage";
			// test.setGenerated(true);
			// test.setGenerateButtonStyleClass("buttonDis");
			// dataTableAccepted.setValue(test);
			System.out.println("acceptedInterviews size=" + acceptedInterviews.size());
		}

		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(event.getComponent().getClientId(), new FacesMessage(s));

	}
	
	public void startTest(){
//		HttpSession httpsession=(HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
//		httpsession.setAttribute(name, value)
//		setCurrentInterviewId(999);
		InterviewDTO test = (InterviewDTO) getDataTableAccepted().getRowData();
		setCurrentInterviewId(test.getId());
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/questions.xhtml");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	public void setDataTableAccepted(HtmlDataTable dataTableAccepted) {
		this.dataTableAccepted = dataTableAccepted;
	}

	public HtmlDataTable getDataTableAccepted() {
		return dataTableAccepted;
	}

	public void setHasPendingInterviews(boolean hasPendingInterviews) {
		this.hasPendingInterviews = hasPendingInterviews;
	}

	public boolean isHasPendingInterviews() {
		return pendingInterviews.size() != 0;
	}

	public void setHasAcceptedInterviews(boolean hasAcceptedInterviews) {
		this.hasAcceptedInterviews = hasAcceptedInterviews;
	}

	public boolean isHasAcceptedInterviews() {
		return acceptedInterviews.size() != 0;
	}

	public void setHasHistory(boolean hasHistory) {
		this.hasHistory = hasHistory;
	}

	public boolean isHasHistory() {
		return allInterviews.size() != 0;
	}

	public void setHasDeclinedInterviews(boolean hasDeclinedInterviews) {
		this.hasDeclinedInterviews = hasDeclinedInterviews;
	}

	public boolean isHasDeclinedInterviews() {
		return declinedInterviews.size() != 0;
	}

	public void setViewTest(boolean viewTest) {
		this.viewTest = viewTest;
	}

	public boolean isViewTest() {
		return viewTest;
	}

	public void setInterviewTest(String interviewTest) {
		this.interviewTest = interviewTest;
	}

	public String getInterviewTest() {
		return interviewTest;
	}

	public void setDataTableHistory(HtmlDataTable dataTableHistory) {
		this.dataTableHistory = dataTableHistory;
	}

	public HtmlDataTable getDataTableHistory() {
		return dataTableHistory;
	}

	public void view() {
		try {
			// setViewTest(true);
			InterviewDTO aI = (InterviewDTO) getDataTableHistory().getRowData();
			setViewDetailsInterview(aI);
			setScorePerCategories(calculateScorePerCategories(aI));
			if (scorePerCategories.size() == 0) {
				setNoScore(true);
				setHasScore(false);
			} else {
				setNoScore(false);
				setHasScore(true);
			}
			setTotalScore(scoreComputationDAO.computeTotalScore(aI.getId()));
			FacesContext.getCurrentInstance().getExternalContext()
					.redirect("/MSGCandidateTesting/faces/viewTest.xhtml");
		} catch (Exception ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}

	}

	public void setViewDetailsInterview(InterviewDTO viewDetailsInterview) {
		this.viewDetailsInterview = viewDetailsInterview;
	}

	public InterviewDTO getViewDetailsInterview() {
		return viewDetailsInterview;
	}

	// public void setTest(InterviewDTO test) {
	// this.test = test;
	// }
	//
	// public InterviewDTO getTest() {
	// return test;
	// }

	public void setScorePerCategories(Map<String, String> scorePerCategories) {
		this.scorePerCategories = scorePerCategories;
	}

	public List<Map.Entry<String, String>> getScorePerCategories() {
		if (scorePerCategories != null) {
			Set<Map.Entry<String, String>> set = scorePerCategories.entrySet();
			return new ArrayList<Map.Entry<String, String>>(set);
		}
		return new ArrayList<Map.Entry<String, String>>();
	}

	public Map<String, String> calculateScorePerCategories(InterviewDTO iDTO) {

		try {
			scorePerCategories = new HashMap<String, String>();
			Map<Integer, List<Float>> categoriesScore = new HashMap<Integer, List<Float>>();
			categoriesScore = scoreComputationDAO.computeCorrectAnswersPerCategories(iDTO.getId());
			for (Map.Entry<Integer, List<Float>> entry : categoriesScore.entrySet()) {
				String s = "";
				s += entry.getValue().get(1);
				s += "/";
				s += entry.getValue().get(0);
				scorePerCategories.put(categoryDAO.getCategoryById(entry.getKey()).getName(), s);
				System.out.println(categoryDAO.getCategoryById(entry.getKey()).getName() + "   " + s);
				// scorePerCategories.put("1", "2");
			}
			// scorePerCategories.put("1", "2");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("!!!!!scorePerCategories size= " + scorePerCategories.size());
		return scorePerCategories;

	}

	public void setTotalScore(float totalScore) {
		this.totalScore = totalScore;
	}

	public float getTotalScore() {
		return totalScore;
	}

	public void setShowPendingInterviews(boolean showPendingInterviews) {
		this.showPendingInterviews = showPendingInterviews;
	}

	public boolean isShowPendingInterviews() {
		return showPendingInterviews;
	}

	public void show1() {
		setShowPendingInterviews(!isShowPendingInterviews());
	}

	public void goBack() {
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect(
					"/MSGCandidateTesting/faces/afterLink.xhtml");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void setHasScore(boolean hasScore) {
		this.hasScore = hasScore;
	}

	public boolean isHasScore() {
		return hasScore;
	}

	public void setNoScore(boolean noScore) {
		this.noScore = noScore;
	}

	public boolean isNoScore() {
		return noScore;
	}

	public void setCandidateDTO(CandidateDTO candidateDTO) {
		this.candidateDTO = candidateDTO;
	}

	public CandidateDTO getCandidateDTO() {
		return candidateDTO;
	}

	/**
	 * @param messageClass
	 *            the messageClass to set
	 */
	public void setMessageClass(String messageClass) {
		this.messageClass = messageClass;
	}

	/**
	 * @return the messageClass
	 */
	public String getMessageClass() {
		return messageClass;
	}

	public void setCurrentInterviewId(int currentInterviewId) {
		this.currentInterviewId = currentInterviewId;
	}

	public int getCurrentInterviewId() {
		return currentInterviewId;
	}
}
